home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Pascal / Games / Showwit! 1.0 / source code / Source / CShAppLevelsDirector.p < prev    next >
Encoding:
Text File  |  1996-01-16  |  10.8 KB  |  389 lines  |  [TEXT/PJMM]

  1. {****************************************************}
  2. {}
  3. {        CShAppLevelsDirector.p                                                                                                                                                                    }
  4. {}
  5. {        Director class for reading in the default levels. Reads the levels from the                 }
  6. {        application resource, and the best players from the preferences file.                             }
  7. {}
  8. {        Although nominally this is a responsibility of the application, because we                    }
  9. {        draw a progress dialog, we need a separate director. This also brings us into     }
  10. {        line with the CShLevelsDoc, in that a separate object reads the levels and                }
  11. {        sends them to the game director.                                                                                                                                         }
  12. {}
  13. {****************************************************}
  14.  
  15.  
  16. unit CShAppLevelsDirector;
  17.  
  18. interface
  19.  
  20.     uses
  21.         TCL, ShIntf;
  22.  
  23. implementation
  24.  
  25.     type
  26.         IntegerH = ^IntegerPtr;
  27.  
  28.     const
  29.         kSTRAppDefaultLevels = 2;
  30.  
  31. {****************************************************}
  32. {}
  33. {        IShAppLevelsDirector                                                                                                                                                                            }
  34. {}
  35. {        Construction of the application levels reader object.                                                                                }
  36. {}
  37. {****************************************************}
  38.  
  39.     procedure CShAppLevelsDirector.IShAppLevelsDirector (aSupervisor: CShApp;
  40.                                     aAppResFile: Integer);
  41.  
  42.     begin { IShAppLevelsDirector }
  43.         itsShApp := aSupervisor;
  44.         itsProgBar := nil;
  45.  
  46.         IDirector(aSupervisor);
  47.  
  48.         itsAppResFile := aAppResFile;
  49.     end; { IShAppLevelsDirector }
  50.  
  51.  
  52. {****************************************************}
  53. {}
  54. {        Free                                                                                                                                                                                                                                }
  55. {}
  56. {     Destruction of the application levels reader object. We set our pointers                         }
  57. {        to nil, for the objects to which they were pointing will be disposed of in                     }
  58. {        inherited methods.                                                                                                                                                                                     }
  59. {}
  60. {****************************************************}
  61.  
  62.     procedure CShAppLevelsDirector.Free;
  63.  
  64.     begin { Free }
  65.         { The window disposes of all the subviews when it is freed. }
  66.         { For completeness, we set our pointers to nil. }
  67.  
  68.         itsShApp := nil;
  69.         itsProgBar := nil;
  70.  
  71.         inherited Free;
  72.     end; { Free }
  73.  
  74.  
  75. {****************************************************}
  76. {}
  77. {        BuildWindow                                                                                                                                                                                                        }
  78. {}
  79. {     Builds the window of the reader.                                                                                                                                             }
  80. {}
  81. {****************************************************}
  82.  
  83.     procedure CShAppLevelsDirector.BuildWindow;
  84.  
  85.         var
  86.             theWindow: CWindow;
  87.             theWindRect: Rect;
  88.  
  89.             thePicture: CPicture;
  90.  
  91.             theReadingStr, theDefaultStr: Str255;
  92.             theEditText: CEditText;
  93.  
  94.             theProgBar: CProgressBar;
  95.  
  96.             theBorder: CPaneBorder;
  97.  
  98.     begin { BuildWindow }
  99.         new(theWindow);
  100.         theWindow.IWindow(WINDReader, kNotFloating, gDesktop, SELF);
  101.         itsWindow := theWindow;
  102.  
  103.         { We don't want the window to be re-sizable. }
  104.  
  105.         SetRect(theWindRect, kReaderWindh, kReaderWindv, kReaderWindh, kReaderWindv);
  106.         itsWindow.SetSizeRect(theWindRect);
  107.  
  108.         { Uses the same window as the documents ie non-modal. }
  109.  
  110.         itsWindow.SetModal(kModeless);
  111.  
  112.         gDecorator.PlaceNewWindow(itsWindow);
  113.         gDecorator.CenterWindow(itsWindow);
  114.  
  115.         { Background picture. }
  116.  
  117.         new(thePicture);
  118.         thePicture.IPicture(itsWindow, SELF, kReaderWindh, kReaderWindv, 0, 0, sizFIXEDSTICKY, sizFIXEDSTICKY);
  119.         if gSystem.hasColorQD then begin
  120.             thePicture.UsePICT(PICTReaderColour);
  121.         end { if }
  122.         else begin
  123.             thePicture.UsePICT(PICTReaderBW);
  124.         end; { else }
  125.         thePicture.SetScaled(FALSE);
  126.  
  127.         { Text saying that we are reading the default levels. }
  128.  
  129.         new(theEditText);
  130.         theEditText.IEditText(itsWindow, SELF, kReaderTextLenh, kReaderTextLenv, kReaderTextPosh, kReaderTextPosv, sizFIXEDSTICKY, sizFIXEDSTICKY, kReaderTextLenh);
  131.         theEditText.Specify(kNotEditable, kNotSelectable, kNotStylable);
  132.         theEditText.SetAlignCmd(cmdAlignLeft);
  133.         theEditText.SetFontNumber(0); { System font, Chicago. }
  134.         GetIndString(theReadingStr, STRlistAppMessages, kSTRAppReading);
  135.         GetIndString(theDefaultStr, STRlistAppMessages, kSTRAppDefaultLevels);
  136.         theEditText.SetTextString(Concat(theReadingStr, ' ', theDefaultStr, '.'));
  137.  
  138.         { Progress bar. }
  139.  
  140.         new(theProgBar);
  141.         theProgBar.IProgressBar(itsWindow, SELF, kReaderProgBarLenh, kReaderProgBarLenv, kReaderProgBarPosh, kReaderProgBarPosv, sizFIXEDSTICKY, sizFIXEDSTICKY, kUseColor, kHorizontal, KNoShadow, FinderFillColor, FinderBackColor);
  142.         itsProgBar := theProgBar;
  143.  
  144.         { Border for the progress bar. }
  145.  
  146.         new(theBorder);
  147.         theBorder.IPaneBorder(kBorderFrame);
  148.         theProgBar.SetBorder(theBorder);
  149.     end; { BuildWindow }
  150.  
  151.  
  152. {****************************************************}
  153. {}
  154. {        AppLevels                                                                                                                                                                                                                }
  155. {}
  156. {     Returns the list of application levels, with best players as they exist.                             }
  157. {        Updates the progress bar whilst doing so.                                                                                                                 }
  158. {}
  159. {****************************************************}
  160.  
  161.     function CShAppLevelsDirector.AppLevels: CList;
  162.  
  163.         var
  164.             theDefLevels: CList;
  165.  
  166.             theBestPlayers: BestArrayHand;
  167.             theNumBestH: IntegerH;
  168.  
  169.             theLevel: CShLevel;
  170.  
  171.             theCount, theNumLevels: Integer;
  172.             theBestCount, theCurrBestLevel, theBestMax: Integer;
  173.  
  174.             theSavedRes: Integer;
  175.  
  176.     begin { AppLevels }
  177.         { Select the window to bring it to the front. }
  178.  
  179.         itsWindow.Select;
  180.  
  181.         { Until now, now updating has been done. }
  182.         { We have to force one now, to correctly draw the picture. }
  183.  
  184.         itsWindow.Update;
  185.  
  186.         new(theDefLevels);
  187.         theDefLevels.IList;
  188.  
  189.         { Get the array of best players from the preference file. }
  190.  
  191.         itsShApp.PreferencesFile.GetPref(kPrefBestPlayers, Handle(theBestPlayers));
  192.         itsShApp.PreferencesFile.GetPref(kPrefNumBest, Handle(theNumBestH));
  193.  
  194.         { Number of best players. }
  195.  
  196.         if (theBestPlayers <> nil) and (theNumBestH <> nil) then begin
  197.             theBestMax := theNumBestH^^;
  198.         end { if }
  199.         else begin
  200.             theBestPlayers := nil;
  201.             theBestMax := 0;
  202.         end; { else }
  203.  
  204.         theBestCount := 1;
  205.         if theBestMax >= 1 then begin
  206. {$PUSH}
  207. {$R-}
  208.             theCurrBestLevel := theBestPlayers^^[1].theLevelNum;
  209. {$POP}
  210.         end; { if }
  211.  
  212.         { Set the initial progress, resetting from any previous run. }
  213.  
  214.         itsProgBar.UpdateProgress(0);
  215.  
  216.         { Read each level from application resource, and place in list. }
  217.  
  218.         theSavedRes := CurResFile;
  219.  
  220.         UseResFile(itsAppResFile);
  221.  
  222.         theNumLevels := Count1Resources(kLEVLResType);
  223.         for theCount := 1 to theNumLevels do begin
  224.  
  225.             { We are now reading resources from the application resource file. }
  226.  
  227.             new(theLevel);
  228.             theLevel.SetLEVL(LEVLDefStart + theCount - 1);
  229.  
  230.             { If a corresponding record exists in the best player handle, use it. }
  231.  
  232.             if (theBestCount <= theBestMax) & (theCount = theCurrBestLevel) then begin
  233. {$PUSH}
  234. {$R-}
  235.                 with theBestPlayers^^[theBestCount] do begin
  236.                     theLevel.SetPlayer(thePlayer);
  237.                     theLevel.SetMoves(theMoves);
  238.                     theLevel.SetTime(theTime);
  239.  
  240.                     theBestCount := theBestCount + 1;
  241.  
  242.                     if theBestMax >= theBestCount then begin
  243.                         theCurrBestLevel := theBestPlayers^^[theBestCount].theLevelNum;
  244.                     end; { if }
  245.                 end; { with }
  246. {$POP}
  247.             end { if }
  248.             else begin
  249.                 theLevel.SetDefaultBestPlayer;
  250.             end; { else }
  251.  
  252.             theDefLevels.InsertAt(theLevel, theCount);
  253.  
  254.             itsProgBar.UpdateProgress(Integer(LongInt(theCount) * 100 div theNumLevels));
  255.  
  256.         end;
  257.  
  258.         UseResFile(theSavedRes);
  259.  
  260.         { Finished with the handle. }
  261.         theBestPlayers := nil;
  262.  
  263.         AppLevels := theDefLevels;
  264.     end; { AppLevels }
  265.  
  266.  
  267. {****************************************************}
  268. {}
  269. {        StoreBestPlayer                                                                                                                                                                                            }
  270. {}
  271. {        Stores the specified best player to the preferences file.                                                                     }
  272. {}
  273. {****************************************************}
  274.  
  275.     procedure CShAppLevelsDirector.StoreBestPlayer (aLevelNum: LevelsRange;
  276.                                     aPlayer: Str15;
  277.                                     aMoves: Integer;
  278.                                     aTime: LongInt);
  279.  
  280.         var
  281.             theBestPlayers, theNewBestPlayers: BestArrayHand;
  282.             theNumBestH: IntegerH;
  283.  
  284.             theBestCount, theBestMax: Integer;
  285.             isPresent: Boolean;
  286.  
  287.     begin { StoreBestPlayer }
  288.         theNewBestPlayers := nil;
  289.  
  290.         itsShApp.PreferencesFile.GetPref(kPrefBestPlayers, Handle(theBestPlayers));
  291.         itsShApp.PreferencesFile.GetPref(kPrefNumBest, Handle(theNumBestH));
  292.  
  293.         { Number of best players. }
  294.  
  295.         if (theBestPlayers = nil) or (theNumBestH = nil) then begin
  296.             theBestPlayers := nil;
  297.             theNumBestH := nil;
  298.             theBestMax := 0;
  299.         end { if }
  300.         else begin
  301.             theBestMax := theNumBestH^^;
  302.         end; { else }
  303.  
  304.         { Scan through the array to see if aLevelNum already has a record. }
  305.         { If so, then use HandToHand to copy the current preference handle }
  306.         { otherwise create a new one with an additional entry. }
  307.         { If there is a failure here, there is nothing to correct locally. We }
  308.         { just allow the error to propagate. }
  309.  
  310.         isPresent := FALSE;
  311.         theBestCount := 1;
  312.         while (not isPresent) and (theBestCount <= theBestMax) do begin
  313. {$PUSH}
  314. {$R-}
  315.             isPresent := theBestPlayers^^[theBestCount].theLevelNum = aLevelNum;
  316. {$POP}
  317.  
  318.             if not isPresent then begin
  319.                 theBestCount := theBestCount + 1;
  320.             end; { if }
  321.         end; { while }
  322.  
  323.         if isPresent then begin
  324.             theNewBestPlayers := theBestPlayers;
  325.  
  326.             if HandToHand(Handle(theNewBestPlayers)) = noErr then begin
  327. {$PUSH}
  328. {$R-}
  329.                 theNewBestPlayers^^[theBestCount].thePlayer := aPlayer;
  330.                 theNewBestPlayers^^[theBestCount].theMoves := aMoves;
  331.                 theNewBestPlayers^^[theBestCount].theTime := aTime;
  332. {$POP}
  333.  
  334.                 itsShApp.PreferencesFile.SetPref(kPrefBestPlayers, Handle(theNewBestPlayers));
  335.                 ForgetHandle(theNewBestPlayers);
  336.             end; { if }
  337.         end { if }
  338.         else begin
  339.  
  340.             SetCriticalOperation(TRUE);
  341.             theNewBestPlayers := BestArrayHand(NewHandleCanFail(SizeOf(BestPlayerRec) * (theBestMax + 1)));
  342.             FailNIL(theNewBestPlayers);
  343.             SetCriticalOperation(FALSE);
  344.  
  345.             { Scan through the levels, and copy them into place. }
  346.  
  347. {$PUSH}
  348. {$R-}
  349.             theBestCount := 1;
  350.             while (theBestCount <= theBestMax) & (theBestPlayers^^[theBestCount].theLevelNum < aLevelNum) do begin
  351.                 theNewBestPlayers^^[theBestCount] := theBestPlayers^^[theBestCount];
  352.                 theBestCount := theBestCount + 1;
  353.             end; { while }
  354.  
  355.             theNewBestPlayers^^[theBestCount].theLevelNum := aLevelNum;
  356.             theNewBestPlayers^^[theBestCount].thePlayer := aPlayer;
  357.             theNewBestPlayers^^[theBestCount].theMoves := aMoves;
  358.             theNewBestPlayers^^[theBestCount].theTime := aTime;
  359.  
  360.             while (theBestCount <= theBestMax) do begin
  361.                 theNewBestPlayers^^[theBestCount + 1] := theBestPlayers^^[theBestCount];
  362.                 theBestCount := theBestCount + 1;
  363.             end; { while }
  364. {$POP}
  365.  
  366.             itsShApp.PreferencesFile.SetPref(kPrefBestPlayers, Handle(theNewBestPlayers));
  367.             ForgetHandle(theNewBestPlayers);
  368.  
  369.             if theNumBestH = nil then begin
  370.                 SetCriticalOperation(TRUE);
  371.                 theNumBestH := IntegerH(NewHandleCanFail(SizeOf(Integer)));
  372.                 FailNIL(theNumBestH);
  373.                 SetCriticalOperation(FALSE);
  374.  
  375.                 theNumBestH^^ := 1;
  376.                 itsShApp.PreferencesFile.SetPref(kPrefNumBest, Handle(theNumBestH));
  377.                 ForgetHandle(theNumBestH);
  378.             end { end }
  379.             else if HandToHand(Handle(theNumBestH)) = noErr then begin
  380.                 theNumBestH^^ := theNumBestH^^ + 1;
  381.                 itsShApp.PreferencesFile.SetPref(kPrefNumBest, Handle(theNumBestH));
  382.                 ForgetHandle(theNumBestH);
  383.             end; { else if }
  384.         end; { else }
  385.  
  386.     end; { StoreBestPlayer }
  387.  
  388.  
  389. end. { CShAppLevelsDirector }